'''
Description: 
Version: 2.0
Autor: zyw
Date: 2022-03-04 11:11:22
LastEditors: zyw
LastEditTime: 2022-03-09 10:27:52
'''
"""
BasePage:封装的是一个所有页面的父类，在父类中封装一些页面常用的操作方法
    1、查找元素
    2、点击元素
    3、输入类容
    4、等待元素可见
    5、等待元素可点击
    6、等待元素存在
    7、获取元素的属性
    8、iframe的切换
    9、错误截图
"""
import os,sys
import allure
import time
base_path = os.path.abspath(os.path.join(os.getcwd(), "."))
sys.path.append(base_path)
from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from common.hand_log import my_log
from common.hand_path import images_path

class BasePage:
    
    def __init__(self,driver: WebDriver):
        self.driver = driver
     
    def find_element(self,loc,desc=None):
        
        """
        查找元素
        :param loc:元素定位器
        :param desc:元素的描述
        """
        try:
            element = self.driver.find_element(*loc)
        except Exception as e:
            my_log.error("查找元素--【{}】--失败".format(desc))
            my_log.exception(e)
            self.error_save_screenshot(desc)
            raise e
        else:
            my_log.info("查找元素--【{}】--成功".format(desc))
        return element
    
    def find_elements(self,loc,desc=None):
        """
        查找多个同样的元素，以列表返回
        :param loc:元素定位器
        :param number:对应元素的下标
        :param desc:元素的描述
        """
        try:
            elements = self.driver.find_elements(*loc)
        except Exception as e:
            my_log.error("查找元素--【{}】--失败".format(desc))
            my_log.exception(e)
            self.error_save_screenshot(desc)
            raise e
        else:
            my_log.info("查找元素--【{}】--成功".format(desc))
        return elements
       
    def input_send_keys(self,loc,value,desc=None):
        """
        输入框,输入元素
        :param loc:input输入框元素定位器
        :param value:输入的内容
        :param desc:元素的描述
        """
        try:
            element = self.driver.find_element(*loc).send_keys(value)
        except Exception as e:
            my_log.error("往输入框--【{}】--输入值失败".format(desc))
            my_log.exception(e)
            self.error_save_screenshot(desc)
            raise e
        else:
            my_log.info("往输入框--【{}】--输入值成功".format(desc))
  
    def click_element(self,loc,desc=None):
        """
        点击元素
        :param loc:元素定位器
        :param desc:元素的描述
        """
        try:
            element = self.driver.find_element(*loc).click()
        except Exception as e:
            my_log.error("点击元素--【{}】--失败".format(desc))
            my_log.exception(e)
            self.error_save_screenshot(desc)
            raise e
        else:
            my_log.info("点击元素--【{}】--成功".format(desc))
           
    def clear_input(self,loc,desc=None):
        """
        清空输入框
        :param loc:input输入框元素定位器
        :param desc:元素的描述
        """
        try:
            element = self.driver.find_element(*loc).clear()
        except Exception as e:
            my_log.error("清空输入框--【{}】--失败".format(desc))
            my_log.exception(e)
            self.error_save_screenshot(desc)
            raise e
        else:
            my_log.info("清空输入框--【{}】--成功".format(desc))
        
    def get_element_text(self,loc,desc=None):
        """
        获取元素的文本
        :param loc:元素定位器
        :param desc:元素的描述
        """
        try:
            text = self.driver.find_element(*loc).text
        except Exception as e:
            my_log.error("查找元素--【{}】--失败".format(desc))
            my_log.exception(e)
            self.error_save_screenshot(desc)
            raise e 
        else:
            my_log.info("查找元素--【{}】--成功".format(desc))
        return text
    
    def wait_element_visible(self,loc,desc):
        """
        等待元素可见
        :param loc:元素定位器
        :param desc:元素的描述
        """
        try:
            element = WebDriverWait(self.driver,10,0.5).until(
            EC.visibility_of_element_located(loc)
        )
        except Exception as e:
            my_log.error("等待元素--【{}】--可见失败".format(desc))
            my_log.exception(e)
            self.error_save_screenshot(desc)
            raise e
        else:
            my_log.info("等待元素--【{}】--可见成功".format(desc))
        return element
    
    def get_element_attribute(self,loc,attr,desc=None):
        """
        获取元素属性
        :param loc:元素定位器
        :param attr:属性名
        :param desc:元素的描述
        """
        try:
            element = self.driver.find_element(*loc).get_attribute(attr)
        except Exception as e:
            my_log.error("获取元素--【{}】--属性失败".format(desc))
            my_log.exception(e)
            self.error_save_screenshot(desc)
            raise e
        else:
            my_log.info("获取元素--【{}】--属性成功".format(desc))
        return element
    
    def switch_to_iframe_loc(self,loc,desc=None):
        """
        通过iframe标签的定位表达式切换
        :param loc:定位表达式
        :param desc:描述
        :return:
        """
        try:
            WebDriverWait(self.driver,10,0.5).until(
                EC.frame_to_be_available_and_switch_to_it(loc)
            )
        except Exception as e:
            my_log.error("等待iframe可见并进行切换--【{}】--失败".format(desc))
            my_log.exception(e)
            self.error_save_screenshot(desc)
            raise e
        else:
            my_log.info("等待iframe可见并进行切换--【{}】--成功".format(desc))
            
    def switch_to_iframe_name(self,name,desc=None):
        """
        通过iframe标签的name属性定位表达式切换
        :param name:iframe标签的name属性
        :param desc:描述
        :return:
        """
        try:
            self.driver.switch_to.frame(name)
        except Exception as e:
            my_log.error("等待iframe可见并进行切换--【{}】--失败".format(desc))
            my_log.exception(e)
            self.error_save_screenshot(desc)
            raise e
        else:
            my_log.info("等待iframe可见并进行切换--【{}】--成功".format(desc))
            
    def error_save_screenshot(self,desc):
        """
        错误截图
        :param desc:图片描述
        """
        date = time.strftime("%Y-%m-%d_%H-%M-%S")
        filename = date + desc + ".png"
        file_path = os.path.join(images_path,filename)
        try:
            self.driver.save_screenshot(file_path)
        except Exception as e:
            my_log.error("对--{}--操作截图失败--".format(desc))
            my_log.exception(e)
            raise e
        else:
            #--------将截图追加到allure报告中---------
            with open(file_path,'rb')as f:
                file = f.read()
                allure.attach(file, "失败截图", allure.attachment_type.PNG)
            #---------------------------------------
            my_log.info("对--{}--操作截图成功--".format(desc))
            my_log.info("图片名称为--{}--".format(filename))
            
